package com.theeviljames.countdown;

import java.util.Stack;

public class Fitness {

	public static final int PLUS = Integer.MAX_VALUE-0;
	public static final int MINUS = Integer.MAX_VALUE-1;
	public static final int MULT = Integer.MAX_VALUE-2;
	public static final int DIV = Integer.MAX_VALUE-3;
	public static final int[] OPS = {PLUS,MINUS,MULT,DIV};
	public static final int score(final Stack<Integer> stack, int target){
		try{
			Stack<Integer> clone = (Stack<Integer>)stack.clone();
			fitness(clone);
			return Math.abs(target - clone.pop());
		}catch(RuntimeException e){ return Integer.MAX_VALUE; }
	}
	private static final void fitness(final Stack<Integer> stack){
		int elem = stack.pop();
		Integer a,b,c;
		switch(elem){
			case PLUS: 
				fitness(stack);
				a = stack.pop();
				fitness(stack);
				b = stack.pop();
				if(a==null ||b==null) stack.push(null);
				c = a+b;
				stack.push(c);
				break;
			case MINUS:
				fitness(stack);
				a = stack.pop();
				fitness(stack);
				b = stack.pop();
				if(a==null ||b==null) stack.push(null);
				c = a-b;
				if(c<0) throw new RuntimeException("Negative result from substraction");
				stack.push(c);
				break;
			case MULT: 
				fitness(stack);
				a = stack.pop();
				fitness(stack);
				b = stack.pop();
				if(a==null ||b==null) stack.push(null);
				c = a*b;
				stack.push(c);
				break;
			case DIV:
				fitness(stack);
				a = stack.pop();
				fitness(stack);
				b = stack.pop();
				if(a==null ||b==null) stack.push(null);
				if(a%b!=0)throw new RuntimeException("Fractional numbers bad");
				c = a/b;
				stack.push(c);
				break;
			default:
				stack.push(elem);
				break;
			
		}
		
	}
	
	public static void main(String[] args) {
		Stack<Integer> vals = new Stack();
		//vals.push(1);
		vals.push(1);
		vals.push(3);
		vals.push(PLUS);
		vals.push(2);
		vals.push(8);
		vals.push(DIV);
		vals.push(MINUS);
		vals.push(4);
		vals.push(2);
		vals.push(MULT);
		vals.push(PLUS);
		Fitness.fitness(vals);
		System.out.println();
	}

}
